﻿using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MiniJob.RestClient;
using MiniJob.Worker.Runtime;

namespace MiniJob.Worker.Host;

/// <summary>
/// Worker健康度定时上报
/// </summary>
/// <param name="logger"></param>
/// <param name="collector"></param>
/// <param name="options"></param>
/// <param name="httpClientFactory"></param>
public class InitHost(
    ILogger<InitHost> logger,
    ISystemMetricsCollector collector,
    IOptions<MiniJobRuntimeOptions> options,
    IRestClient httpClientFactory)
    : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        if (options.Value.ServerAddress.IsNullOrWhiteSpace())
        {
            logger.LogWarning("no available server,fail to report health info!");
            return;
        }

        Print();

        var localBindIp = WorkerNetUtils.IPV4();

        logger.LogInformation("localBindIp: {LocalBindIp}, localBindPort: {LocalBindPort}", localBindIp, options.Value.Port);

        while (!stoppingToken.IsCancellationRequested)
        {
            WorkerHeartbeat heartbeat = new()
            {
                AppName = options.Value.AppName,
                WorkerAddress = options.Value.WorkerAddress,
                HeartbeatTime = DateTime.Now,
                Metrics = collector.Collect(),
                Tag = options.Value.Tag,
            };

            logger.LogInformation("report health status,appName:{AppName}", heartbeat.AppName);

            await httpClientFactory.PostAsync($"{options.Value.ServerAddress}/server/workerHeartbeat", heartbeat, cancellationToken: stoppingToken);

            await Task.Delay(10000, stoppingToken);
        }
    }

    private void Print()
    {
        logger.LogInformation(JobStr);

        var version = typeof(InitHost).Assembly.GetName().Version;
        logger.LogInformation(":: MiniJob Version :: {Version}", version);
    }

    private static readonly string JobStr = """

         __  __   _           _          _           _     
        |  \/  | (_)         (_)        | |         | |    
        | \  / |  _   _ __    _         | |   ___   | |__  
        | |\/| | | | | '_ \  | |    _   | |  / _ \  | '_ \ 
        | |  | | | | | | | | | |   | |__| | | (_) | | |_) |
        |_|  |_| |_| |_| |_| |_|    \____/   \___/  |_.__/ 

                                                           
        """;
}
